package com.boronstream.istar.utils;

import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.json.JSONArray;
import org.json.JSONObject;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.telephony.NeighboringCellInfo;
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaCellLocation;
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
import android.util.Log;

import com.boronstream.istar.model.AppInfo;

public class MiscUtils {
	private final static String TAG = MiscUtils.class.getSimpleName();

	static class CellIDInfo {

		public int cellId;
		public String mobileCountryCode;
		public String mobileNetworkCode;
		public int locationAreaCode;
		public String radioType;

		public CellIDInfo() {
		}
	}

	static class WifiInfo {

		public String mac;

		public WifiInfo() {
		}
	}

	public static void updateFileTime(String dir, String fileName) {
		File file = new File(dir, fileName);
		long newModifiedTime = System.currentTimeMillis();
		file.setLastModified(newModifiedTime);
	}

	public static boolean checkNet(Context context) {
		ConnectivityManager manager = (ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo info = manager.getActiveNetworkInfo();
		if (info != null) {
			return true;
		}
		return false;
	}

	public static String getAPN(Context context) {
		String apn = "";
		ConnectivityManager manager = (ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo info = manager.getActiveNetworkInfo();

		if (info != null) {
			if (ConnectivityManager.TYPE_WIFI == info.getType()) {
				apn = info.getTypeName();
				if (apn == null) {
					apn = "wifi";
				}
			} else {
				apn = info.getExtraInfo().toLowerCase();
				if (apn == null) {
					apn = "mobile";
				}
			}
		}
		return apn;
	}

	public static String getModel(Context context) {
		return Build.MODEL;
	}

	public static String getHardware(Context context) {
		if (getPhoneSDK(context) < 8) {
			return "undefined";
		} else {
			Log.d(TAG, "hardware:" + Build.HARDWARE);
		}
		return Build.HARDWARE;
	}

	public static String getManufacturer(Context context) {
		return Build.MANUFACTURER;
	}

	public static String getFirmware(Context context) {
		return Build.VERSION.RELEASE;
	}

	public static String getSDKVer() {
		return Integer.valueOf(Build.VERSION.SDK_INT).toString();
	}

	public static String getLanguage() {
		Locale locale = Locale.getDefault();
		String languageCode = locale.getLanguage();
		if (TextUtils.isEmpty(languageCode)) {
			languageCode = "";
		}
		return languageCode;
	}

	public static String getCountry() {
		Locale locale = Locale.getDefault();
		String countryCode = locale.getCountry();
		if (TextUtils.isEmpty(countryCode)) {
			countryCode = "";
		}
		return countryCode;
	}

	public static final int APP_TYPE_ALL = 0;
	public static final int APP_TYPE_USER = 1;
	public static final int APP_TYPE_SYSTEM = 2;

	public static List<AppInfo> getAppInfoList(Context context, int app_type) {
		if (context == null) {
			Log.w(TAG, "getAppInfoList==>" + context + "," + app_type);
			return null;
		}
		Log.v(TAG, "getAppInfoList,build.verion.sdk_int:"
				+ Build.VERSION.SDK_INT);
		PackageManager pm = context.getPackageManager();
		List<PackageInfo> pakageinfos = pm
				.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);
		List<AppInfo> appInfoList = new ArrayList<AppInfo>();
		for (PackageInfo packageInfo : pakageinfos) {
			AppInfo appInfo = new AppInfo();

			try {
				String appName = (packageInfo.applicationInfo != null ? (packageInfo.applicationInfo
						.loadLabel(pm)) : ("")).toString();
				appInfo.setApp_name(appName);
			} catch (Exception e) {
				Log.e(TAG, "getAppName exception:" + e.getMessage());
				e.printStackTrace();
			}

			String versionName = packageInfo.versionName;
			int versionCode = packageInfo.versionCode;
			appInfo.setVersion_name(versionName);
			appInfo.setVersion_code(versionCode);

			boolean isUserApp = isUserApp(packageInfo.applicationInfo);
			appInfo.setApp_type((isUserApp ? "user" : "system"));

			String packageName = packageInfo.packageName;
			appInfo.setPackage_name(packageName);

			long firstInstallTime = packageInfo.firstInstallTime;
			appInfo.setInstall_time(firstInstallTime);
			
//			packageInfo.applicationInfo.
			appInfo.setUpdate_time(packageInfo.lastUpdateTime);
			if (appInfo.getUpdate_time() == 0) {
				ApplicationInfo applicationInfo = packageInfo.applicationInfo;
				final String fileDir = applicationInfo.sourceDir;
				File appFile = new File(fileDir);
				if (appFile.exists()) {
					long UpdateTime = appFile.lastModified();
					appInfo.setUpdate_time(UpdateTime);
				}
			}
			if (appInfo.getInstall_time()==0) {
				appInfo.setInstall_time(appInfo.getUpdate_time());
			}

			switch (app_type) {
			case APP_TYPE_ALL:
				appInfoList.add(appInfo);
				break;
			case APP_TYPE_USER:
				if (isUserApp) {
					appInfoList.add(appInfo);
				}
				break;
			case APP_TYPE_SYSTEM:
				if (!isUserApp) {
					appInfoList.add(appInfo);
				}
				break;
			default:
				break;
			}
		}
		Log.v(TAG, "getAppInfoList size==>" + appInfoList.size());
		return appInfoList;
	}
	
	public static JSONArray getAppInfoArray(Context context, int app_type)
	{
		JSONArray jsonArray = new JSONArray();
		List<AppInfo> appInfos = getAppInfoList(context, app_type);
		if (appInfos!=null) {
			for (AppInfo appInfo : appInfos) {
				jsonArray.put(appInfo.toJsonObject());
			}
		}
		return jsonArray;
	}

	private static boolean isUserApp(ApplicationInfo info) {
		if ((info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
			return true;
		} else if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
			return true;
		}
		return false;
	}

	public static String getIMEI(Context context) {
		TelephonyManager mTelephonyMgr = (TelephonyManager) context
				.getSystemService(Context.TELEPHONY_SERVICE);
		String imei;

		// if ((Build.MODEL.equals("sdk")) ||
		// (Build.MODEL.equals("google_sdk"))) {
		// imei = "Simulator" + "_" + System.currentTimeMillis();
		// } else {
		imei = mTelephonyMgr.getDeviceId();
		if (TextUtils.isEmpty(imei) || imei.equals("000000000000000")) {
			// SharedPreferences sp = context.getSharedPreferences(
			// CommonDefine.APP_PREF_FILE, Context.MODE_PRIVATE);
			// imei = sp.getString("android.os.SystemProperties.DeviceId", "");
			// if (imei.length() < 1) {
			// imei = "0000" + System.currentTimeMillis();
			// Editor editor = sp.edit();
			// editor.putString("android.os.SystemProperties.DeviceId",
			// imei);
			// editor.commit();
			// }
		}
		// }
		// boolean isimei = imei.matches("[0-9]{15}");
		// if (!isimei) {
		// imei = imei.replaceAll("[^0-9]", "0");
		// }
		// //TODO:This is not available on CDMA phone
		// if (imei.length() > 15) {
		// imei = imei.substring(15, imei.length());
		// }else if (imei.length()<15) {
		// imei = imei+"000000000000000".substring(imei.length());
		// }
		return imei;
	}

	public static String getIMSI(Context context) {
		TelephonyManager mTelephonyMgr = (TelephonyManager) context
				.getSystemService(Context.TELEPHONY_SERVICE);
		String imsi = mTelephonyMgr.getSubscriberId();
		if (TextUtils.isEmpty(imsi)) {
			return "0";
		} else {
			return imsi;
		}
	}

	public static String getMcnc(Context context) {

		TelephonyManager tm = (TelephonyManager) context
				.getSystemService(Context.TELEPHONY_SERVICE);
		String mcnc = tm.getNetworkOperator();
		if (TextUtils.isEmpty(mcnc)) {
			return "0";
		} else {
			return mcnc;
		}
	}

	/**
	 * Get phone SDK version
	 * 
	 * @return
	 */
	public static int getPhoneSDK(Context mContext) {
		TelephonyManager phoneMgr = (TelephonyManager) mContext
				.getSystemService(Context.TELEPHONY_SERVICE);
		Log.i(TAG, "Bild model:" + Build.MODEL);
		Log.i(TAG, "Phone Number:" + phoneMgr.getLine1Number());
		Log.i(TAG, "SDK VERSION:" + Build.VERSION.SDK_INT);
		Log.i(TAG, "SDK RELEASE:" + Build.VERSION.RELEASE);
		int sdk = Build.VERSION.SDK_INT;
		return sdk;
	}

	public static Object getMetaData(Context context, String keyName) {
		try {
			ApplicationInfo info = context.getPackageManager()
					.getApplicationInfo(context.getPackageName(),
							PackageManager.GET_META_DATA);

			Bundle bundle = info.metaData;
			Object value = bundle.get(keyName);
			return value;
		} catch (NameNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}

	public static String getAppVersion(Context context) {
		PackageManager pm = context.getPackageManager();
		PackageInfo pi;
		try {
			pi = pm.getPackageInfo(context.getPackageName(), 0);
			String versionName = pi.versionName;
			return versionName;
		} catch (NameNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}

	public static String getSerialNumber(Context context) {
		String serial = null;
		try {
			Class<?> c = Class.forName("android.os.SystemProperties");
			Method get = c.getMethod("get", String.class);
			serial = (String) get.invoke(c, "ro.serialno");
			if (serial == null || serial.trim().length() <= 0) {
				TelephonyManager tManager = (TelephonyManager) context
						.getSystemService(Context.TELEPHONY_SERVICE);
				serial = tManager.getDeviceId();
			}
			Log.d(TAG, "Serial:" + serial);
		} catch (Exception ignored) {
			ignored.printStackTrace();
		}
		return serial;
	}

	// public static boolean hasStorage() {
	// boolean hasStorage = false;
	// String str = Environment.getExternalStorageState();
	//
	// if (str.equalsIgnoreCase(Environment.MEDIA_MOUNTED)) {
	// hasStorage = checkFsWritable();
	// }
	//
	// return hasStorage;
	// }

	// public static int freeSpaceOnSd() {
	// int freeSize = 0;
	//
	// if (hasStorage()) {
	// StatFs statFs = new StatFs(CommonDefine.APP_SDCARD_FOLDER);
	//
	// try {
	// long nBlocSize = statFs.getBlockSize();
	// long nAvailaBlock = statFs.getAvailableBlocks();
	// freeSize = (int) (nBlocSize * nAvailaBlock / 1024 / 1024);
	//
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	// }
	// return freeSize;
	// }

	// public static boolean checkFsWritable() {
	//
	// File directory = new File(CommonDefine.APP_SDCARD_FOLDER);
	// if (!directory.isDirectory()) {
	// if (!directory.mkdirs()) {
	// Log.e(TAG, "checkFsWritable directoryName 000  ");
	// return false;
	// }
	// }
	// File f = new File(CommonDefine.APP_SDCARD_FOLDER, ".probe");
	// try {
	// // Remove stale file if any
	// if (f.exists()) {
	// f.delete();
	// }
	// if (!f.createNewFile()) {
	// return false;
	// }
	// f.delete();
	// return true;
	// } catch (IOException ex) {
	// return false;
	// }
	// }

	public static String getLocationInfo(Context context) {
		ArrayList<WifiInfo> wifi = getWifiInfo(context);
		ArrayList<CellIDInfo> cellID = getCellIDInfo(context);

		JSONObject holder = new JSONObject();
		try {
			JSONObject data, current_data;
			JSONArray array = new JSONArray();

			holder.put("version", "1.1.0");
			holder.put("host", "maps.google.com");
			holder.put("request_address", true);
			holder.put("address_language", "en_US");

			if (cellID != null && cellID.size() > 0) {
				holder.put("home_mobile_country_code",
						cellID.get(0).mobileCountryCode);
				holder.put("home_mobile_network_code",
						cellID.get(0).mobileNetworkCode);
				holder.put("radio_type", cellID.get(0).radioType);
				if ("460".equals(cellID.get(0).mobileCountryCode)) {
					holder.put("address_language", "zh_CN");
				}

				current_data = new JSONObject();
				current_data.put("cell_id", cellID.get(0).cellId);
				current_data.put("location_area_code",
						cellID.get(0).locationAreaCode);
				current_data.put("mobile_country_code",
						cellID.get(0).mobileCountryCode);
				current_data.put("mobile_network_code",
						cellID.get(0).mobileNetworkCode);
				current_data.put("age", 0);
				array.put(current_data);
				if (cellID.size() > 2) {
					for (int i = 1; i < cellID.size(); i++) {
						data = new JSONObject();
						data.put("cell_id", cellID.get(i).cellId);
						data.put("location_area_code",
								cellID.get(i).locationAreaCode);
						data.put("mobile_country_code",
								cellID.get(i).mobileCountryCode);
						data.put("mobile_network_code",
								cellID.get(i).mobileNetworkCode);
						data.put("age", 0);
						array.put(data);
					}
				}
				holder.put("cell_towers", array);
			}

			if (wifi != null && wifi.size() > 0 && wifi.get(0).mac != null) {
				data = new JSONObject();
				array = new JSONArray();
				data.put("mac_address", wifi.get(0).mac);
				data.put("signal_strength", 8);
				data.put("age", 0);
				array = new JSONArray();
				array.put(data);
				holder.put("wifi_towers", array);
			}

			Log.i(TAG, "getLocationInfo location info == " + holder.toString());
		} catch (Exception e) {
			e.printStackTrace();
			Log.e(TAG, "getLocationInfo e == " + e);
			return null;
		}

		return holder.toString();
	}

	private static ArrayList<WifiInfo> getWifiInfo(Context context) {
		ArrayList<WifiInfo> wifi = new ArrayList<WifiInfo>();

		WifiManager wm = (WifiManager) context
				.getSystemService(Context.WIFI_SERVICE);
		WifiInfo info = new WifiInfo();
		info.mac = wm.getConnectionInfo().getBSSID();
		Log.i(TAG, "getWifiInfo info.mac == " + info.mac);
		wifi.add(info);
		return wifi;
	}

	private static ArrayList<CellIDInfo> getCellIDInfo(Context context) {
		TelephonyManager manager = (TelephonyManager) context
				.getSystemService(Context.TELEPHONY_SERVICE);

		ArrayList<CellIDInfo> CellID = new ArrayList<CellIDInfo>();
		CellIDInfo currentCell = new CellIDInfo();

		int type = manager.getNetworkType();
		Log.d(TAG, "getCellIDInfo-->         NetworkType = " + type);
		int phoneType = manager.getPhoneType();
		Log.d(TAG, "getCellIDInfo-->         phoneType = " + phoneType);

		if (type == TelephonyManager.NETWORK_TYPE_GPRS // GSM网
				|| type == TelephonyManager.NETWORK_TYPE_EDGE
				|| type == TelephonyManager.NETWORK_TYPE_HSDPA) {
			Log.d(TAG, "getCellIDInfo gsm");
			GsmCellLocation gsm = ((GsmCellLocation) manager.getCellLocation());
			if (gsm == null) {
				Log.e(TAG, "GsmCellLocation is null!!!");
				return null;
			}

			int lac = gsm.getLac();
			String mcc = (manager.getNetworkOperator() != null && manager
					.getNetworkOperator().length() >= 3) ? manager
					.getNetworkOperator().substring(0, 3) : "";
			String mnc = (manager.getNetworkOperator() != null && manager
					.getNetworkOperator().length() >= 5) ? manager
					.getNetworkOperator().substring(3, 5) : "";
			int cid = gsm.getCid();
			currentCell.cellId = cid;

			currentCell.mobileCountryCode = mcc;
			currentCell.mobileNetworkCode = mnc;
			currentCell.locationAreaCode = lac;

			currentCell.radioType = "gsm";

			CellID.add(currentCell);

			// 获得邻近基站信息
			List<NeighboringCellInfo> list = manager.getNeighboringCellInfo();
			int size = list != null ? list.size() : 0;
			for (int i = 0; i < size; i++) {

				CellIDInfo info = new CellIDInfo();
				info.cellId = list.get(i).getCid();
				info.mobileCountryCode = mcc;
				info.mobileNetworkCode = mnc;
				info.locationAreaCode = lac;

				CellID.add(info);
			}

		} else if (type == TelephonyManager.NETWORK_TYPE_CDMA // 电信cdma网
				|| type == TelephonyManager.NETWORK_TYPE_1xRTT
				|| type == TelephonyManager.NETWORK_TYPE_EVDO_0
				|| type == TelephonyManager.NETWORK_TYPE_EVDO_A) {
			Log.d(TAG, "getCellIDInfo cdma");

			CdmaCellLocation cdma = (CdmaCellLocation) manager
					.getCellLocation();
			if (cdma == null) {
				Log.e(TAG, "CdmaCellLocation is null!!!");
				return null;
			}

			int lac = cdma.getNetworkId();
			String mcc = manager.getNetworkOperator() != null
					&& manager.getNetworkOperator().length() >= 3 ? manager
					.getNetworkOperator().substring(0, 3) : "";
			String mnc = String.valueOf(cdma.getSystemId());
			int cid = cdma.getBaseStationId();

			currentCell.cellId = cid;
			currentCell.mobileCountryCode = mcc;
			currentCell.mobileNetworkCode = mnc;
			currentCell.locationAreaCode = lac;

			currentCell.radioType = "cdma";

			CellID.add(currentCell);

			// 获得邻近基站信息
			List<NeighboringCellInfo> list = manager.getNeighboringCellInfo();
			int size = list != null ? list.size() : 0;
			for (int i = 0; i < size; i++) {

				CellIDInfo info = new CellIDInfo();
				info.cellId = list.get(i).getCid();
				info.mobileCountryCode = mcc;
				info.mobileNetworkCode = mnc;
				info.locationAreaCode = lac;

				CellID.add(info);
			}
		}

		Log.d(TAG, "getCellIDInfo cellID count == " + CellID.size());
		return CellID;
	}

}
